Skip to main content

VOIP/Video Consultations

VoipConfig Object

interface VoipConfig {
id?: number;
consultation_id?: number;
api_key?: string;
call_id?: string;
token?: string;
created_at?: string;
updated_at?: string;
}

For VOIP consultation the config data will be in voipConfig and for VIDEO will be in videoConfig, but they share the same data structure so we use one interface for both: VoipConfig.

VOIP and Video consultations are rendered and handled the same way. The difference is to enable the video on Video consultations and disable it for VOIP consultations.

VOIP/Video Components

These are the components available to handle these consultations:

TBIPublisher
TBISession
TBISubscriber
TBISubscriberView

VOIP/Video Example

Check the below code example of using our ready-to-use components to handle VOIP/Video consultations:

import React, { useRef, useState } from 'react';
import {
TBIPublisher,
TBISession,
TBISubscriber,
TBISubscriberView,
} from 'react-native-altibbi';
import { Dimensions, View, Text } from 'react-native';

const Video = (props) => {
const data = props.route.params.event;
const voip = props.route.params.voip;

const [audio, setAudio] = useState<boolean>(true);
const [video, setVideo] = useState<boolean>(!voip);
const [camera, setCamera] = useState<'front' | 'back'>('front');
const sessionRef = useRef(null);

const toggleVideo = () => setVideo((prev) => !prev);
const toggleAudio = () => setAudio((prev) => !prev);
const switchCamera = () =>
setCamera((prev) => {
if (prev === 'front') {
return 'back';
} else {
return 'front';
}
});

const renderSubscribers = (subscribers) => {
if (subscribers && subscribers.length > 0) {
const { width: screenWidth, height: screenHeight } =
Dimensions.get('window');
return subscribers.map((streamId) => (
<TBISubscriberView
streamId={streamId}
style={{ width: screenWidth, height: screenHeight }}
/>
));
}
};

return (
<TBISession
options={{
androidZOrder: 'onTop',
androidOnTop: 'publisher',
}}
ref={(ref) => (sessionRef.current = ref)}
apiKey={data.api_key}
sessionId={data.call_id}
token={data.token}
eventHandlers={{
streamDestroyed: (event) => {},
error: (event) => {},
otrnError: (event) => {},
}}
>
<TBISubscriber
eventHandlers={{
error: (event) => {},
otrnError: (event) => {},
}}
>
{renderSubscribers}
</TBISubscriber>
<TBIPublisher
style={{
position: 'absolute',
width: 100,
height: 100,
top: 0,
margin: 5,
right: 0,
}}
properties={{
cameraPosition: camera,
publishVideo: video,
publishAudio: audio,
enableDtx: true,
}}
eventHandlers={{
streamDestroyed: (event) => {},
error: (event) => {},
otrnError: (event) => {},
}}
/>
<View
style={{
flexDirection: 'row',
padding: 8,
position: 'absolute',
backgroundColor: 'white',
bottom: 0,
left: 0,
right: 0,
justifyContent: 'center',
}}
>
<Text
style={{
fontSize: 20,
marginRight: 10,
color: video ? 'blue' : 'red',
}}
onPress={() => toggleVideo()}
>
{`Video ${video ? 'On' : 'Off'}`}
</Text>
<Text
style={{
fontSize: 20,
marginRight: 10,
color: audio ? 'blue' : 'red',
}}
onPress={() => toggleAudio()}
>
{`Audio ${audio ? 'On' : 'Off'}`}
</Text>
<Text
style={{ fontSize: 20, marginRight: 10 }}
onPress={() => switchCamera()}
>
camera ({camera})
</Text>
</View>
</TBISession>
);
};

export default Video;